package com.smart.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.smart.common.PageInfo;
import com.smart.common.enums.OperateModuleEnum;
import com.smart.common.enums.OperateTypeEnum;
import com.smart.common.enums.SuperviseModuleEnum;
import com.smart.common.service.LogService;
import com.smart.common.utils.AssertUtil;
import com.smart.mapper.ProjectMapper;
import com.smart.model.convert.ProjectConvert;
import com.smart.model.domain.JiansheProjectDO;
import com.smart.model.domain.ProjectDO;
import com.smart.model.dtomapper.JiansheUnitDtoMapper;
import com.smart.model.domain.JiansheUnitDO;
import com.smart.mapper.JiansheUnitMapper;
import com.smart.model.request.JiansheUnitAddRequest;
import com.smart.model.request.JiansheUnitDeleteProjectRequest;
import com.smart.model.request.JiansheUnitRequest;
import com.smart.model.request.JiansheUnitUpdateRequest;
import com.smart.model.vo.JiansheProjectVO;
import com.smart.model.vo.ProjectVO;
import com.smart.service.JiansheProjectService;
import com.smart.service.JiansheUnitService;
import com.smart.model.convert.JiansheUnitConvert;
import com.smart.model.vo.JiansheUnitVO;
import com.smart.service.ProjectService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.Message;
import java.util.List;
import java.util.Objects;

/**
 * @author zhanghong
 */
@Service
public class JiansheUnitServiceImpl extends ServiceImpl<JiansheUnitMapper, JiansheUnitDO> implements JiansheUnitService {
    @Autowired
    private JiansheUnitMapper jiansheUnitMapper;
    @Autowired
    private JiansheProjectService jiansheProjectService;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private LogService logService;

    @Override
    public JiansheUnitVO getByKey(long id) {
        JiansheUnitDO jiansheUnitDO = getById(id);
        JiansheUnitVO jiansheUnitVO = JiansheUnitDtoMapper.INSTANCE.do2VO(jiansheUnitDO);
        List<ProjectDO> projects = projectMapper.listByJianSheId(jiansheUnitVO.getId());
        if (CollectionUtils.isNotEmpty(projects)) {
            jiansheUnitVO.setProjects(ProjectConvert.buildProjectVoList(projects));
        }
        return jiansheUnitVO;
    }

    @Override
    public PageInfo<JiansheUnitVO> pageQuery(JiansheUnitRequest request) {
        long count = jiansheUnitMapper.pageCount(request);
        List<JiansheUnitDO> list = jiansheUnitMapper.pageQuery(request, request.getPageSize(), request.fetchOffSet());
        List<JiansheUnitVO> jiansheUnitVOList = JiansheUnitConvert.buildJiansheUnitVoList(list);
        jiansheUnitVOList.forEach(item -> {
            List<ProjectDO> projects = projectMapper.listByJianSheId(item.getId());
            if (CollectionUtils.isNotEmpty(projects)) {
                item.setProjects(ProjectConvert.buildProjectVoList(projects));
            }
        });
        return new PageInfo(request.getPageNum(), request.getPageSize(), jiansheUnitVOList, count);
    }

    @Override
    public List<JiansheUnitVO> listQuery(JiansheUnitRequest request) {
        List<JiansheUnitDO> list = list();
        List<JiansheUnitVO> jiansheUnitVOS = JiansheUnitConvert.buildJiansheUnitVoList(list);
        jiansheUnitVOS.forEach(item -> {
            List<ProjectDO> projects = projectMapper.listByJianSheId(item.getId());
            if (CollectionUtils.isNotEmpty(projects)) {
                item.setProjects(ProjectConvert.buildProjectVoList(projects));
            }
        });
        return jiansheUnitVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(JiansheUnitAddRequest request) {
        //前置校验
        boolean exists = lambdaQuery().eq(JiansheUnitDO::getAccount, request.getAccount()).exists();
        AssertUtil.assertFalse(exists, "用户名已存在");

        JiansheUnitDO jiansheUnitDO = JiansheUnitDtoMapper.INSTANCE.request2DO(request);
        jiansheUnitDO.setPassword(request.getAccount());
        save(jiansheUnitDO);
        if (CollectionUtils.isNotEmpty(request.getProjects())) {
            //添加关联项目
            List<JiansheProjectDO> jiansheProjectDOList = Lists.newArrayList();
            for (Long projectId : request.getProjects()) {
                ProjectVO byKey = projectService.getByKey(projectId);
                AssertUtil.assertNotNull(byKey, "提交项目中有不存在的项目，请检查");
                jiansheProjectDOList.add(JiansheProjectDO.builder().projectId(projectId).jiansheUnitId(jiansheUnitDO.getId()).build());
            }
            // 添加
            jiansheProjectService.saveBatch(jiansheProjectDOList);
        }

        //记录操作日志
        String afterContent = JSON.toJSONString(getById(jiansheUnitDO.getId()));
        logService.logSupervisePlatformAddScene(SuperviseModuleEnum.建设单位管理, jiansheUnitDO.getId(), afterContent);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByKey(JiansheUnitUpdateRequest request) {
        //前置校验
        List<ProjectDO> list = projectService.lambdaQuery().eq(ProjectDO::getAccount, request.getAccount()).list();
        if (CollectionUtils.isNotEmpty(list)) {
            AssertUtil.assertTrue(list.size() == 1, "用户名已存在");
        }

        JiansheUnitDO jiansheUnitDO = JiansheUnitDtoMapper.INSTANCE.request2DO(request);
        saveOrUpdate(jiansheUnitDO);
        if (CollectionUtils.isNotEmpty(request.getProjects())) {
            //删除
            jiansheProjectService.lambdaUpdate().eq(JiansheProjectDO::getJiansheUnitId, jiansheUnitDO.getId()).remove();

            //添加关联项目
            List<JiansheProjectDO> jiansheProjectDOList = Lists.newArrayList();
            for (Long projectId : request.getProjects()) {
                ProjectVO byKey = projectService.getByKey(projectId);
                AssertUtil.assertNotNull(byKey, "提交项目中有不存在的项目，请检查");
                jiansheProjectDOList.add(JiansheProjectDO.builder().projectId(projectId).jiansheUnitId(jiansheUnitDO.getId()).build());
            }
            // 添加
            jiansheProjectService.saveBatch(jiansheProjectDOList);
        } else {
            //删除
            jiansheProjectService.lambdaUpdate().eq(JiansheProjectDO::getJiansheUnitId, jiansheUnitDO.getId()).remove();
        }

        //记录操作日志
        String beforeContent = JSON.toJSONString(jiansheUnitDO);
        String afterContent = JSON.toJSONString(getById(jiansheUnitDO.getId()));
        logService.logSupervisePlatformUpdateScene(SuperviseModuleEnum.建设单位管理, jiansheUnitDO.getId(), beforeContent, afterContent);
        return true;
    }

    @Override
    public Boolean deleteProject(JiansheUnitDeleteProjectRequest request) {
        JiansheUnitDO jiansheUnitDO = jiansheUnitMapper.selectDOById(request.getJianSheUnitId());
        AssertUtil.assertNotNull(jiansheUnitDO, "建设单位不存在");

        List<JiansheProjectDO> projects = jiansheProjectService.lambdaQuery()
                .eq(JiansheProjectDO::getJiansheUnitId, request.getJianSheUnitId()).list();
        AssertUtil.assertNotEmpty(projects, "建设单位下不存在该项目");
        Long count = projects.stream().map(JiansheProjectDO::getProjectId).filter(projectId -> Objects.equals(projectId, request.getProjectId())).count();
        AssertUtil.assertTrue(count != 0, "建设单位下不存在该项目");

        jiansheProjectService.lambdaUpdate().eq(JiansheProjectDO::getJiansheUnitId, request.getJianSheUnitId())
                .eq(JiansheProjectDO::getProjectId, request.getProjectId())
                .remove();
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean resetPassword(long id) {
        JiansheUnitDO jiansheUnitDO = jiansheUnitMapper.selectDOById(id);
        AssertUtil.assertNotNull(jiansheUnitDO, "建设单位不存在");
        jiansheUnitDO.setPassword(jiansheUnitDO.getAccount());
        saveOrUpdate(jiansheUnitDO);

        //记录操作日志
        String beforeContent = JSON.toJSONString(jiansheUnitDO);
        String afterContent = JSON.toJSONString(getById(jiansheUnitDO.getId()));
        logService.logSupervisePlatform(SuperviseModuleEnum.建设单位管理, OperateTypeEnum.修改, jiansheUnitDO.getId(), beforeContent, afterContent, "重置密码");
        return true;
    }

    @Override
    public List<ProjectVO> queryByName(String unitName) {
        List<ProjectDO> list = projectService.lambdaQuery().eq(ProjectDO::getJiansheUnit, unitName).eq(ProjectDO::getValid, 1).list();
        return ProjectConvert.buildProjectVoList(list);
    }
}
